<template>
  <div>
    <div :style="{fontSize: '14px',height: '40px', lineHeight: '40px', display: 'flex'}">
      <span>共计</span>
      <span style="color:#337ab7">{{pageInfo.pagination.total}}</span>
      <span>条相关信息</span>
      <div :style="{flex: 1, textAlign: 'right',marginRight: '20px'}">
        <Divider type="vertical" />
        <slot />
      </div>
    </div>
    <Table
      :columns="columnsData"
      :data="pageInfo.list"
      border
      size="small"
      :loading="loading"
      @on-selection-change="handleSelectChange"
      @on-sort-change="handleSortChange"
    />
    <div :style="{textAlign: 'right'}" v-if="showPageInfo">
      <Page
        :total="pageInfo.pagination.total"
        :current="pageInfo.pagination.current_page"
        :page-size="pageInfo.pagination.page_size"
        :show-total="true"
        :show-elevator="true"
        show-sizer
        :page-size-opts="[16, 32, 64, 128]"
        @on-change="handlePageChange"
        @on-page-size-change="handlePageSizeChange"
      />
    </div>
  </div>
</template>
<style lang="less">
</style>
<script>
import { Table, Page, Divider } from "view-design";
import appService from "@/utils/appService";
import compare from "@/utils/compare";
export default {
  name: "RemoteTable",
  props: {
    /** vuex module名称 */
    namespace: String,
    /** 渲染列 */
    columns: Array,
    /** 是否显示分页 */
    showPageInfo: {
      type: Boolean,
      default: true
    },
    /** 是否需要参数才抓取数据 */
    needQueryParam: {
      type: Boolean,
      default: false,
      required: false
    },
    /** 查询参数 */
    queryParam: Object,
    /** 数据的唯一性key */
    primaryKey: {
      type: String,
      default: "id"
    },
    /** 选中项目 */
    selected: {
      type: Array,
      default: () => [],
      required: false
    }
  },
  model: {
    event: [
      "on-selection-change",
      "onSelectionChange",
      "onSelectCancel",
      "onSortChange"
    ]
  },
  components: {
    Table,
    Page,
    Divider
  },
  beforeMount() {
    this.cleanData();
    this.loadData();
  },
  watch: {
    namespace: function(newValue, oldValue) {
      this.loadData();
    },
    queryParam: function(newValue, oldValue) {
      if (!compare(newValue, oldValue)) {
        this.loadData();
      }
    }
  },
  data: function() {
    return {
      /** 当前tables中存在且选中的行 */
      selectedRows: []
    };
  },
  computed: {
    pageInfo: function() {
      let namespace = this.$props.namespace;
      let pageInfo = this.$store.state[namespace].pageInfo;
      if (!pageInfo) {
        pageInfo = {};
      }
      if (!pageInfo.pagination) {
        pageInfo.pagination = {
          total: 0
        };
      }
      if (!pageInfo.list) {
        pageInfo.list = [];
      }
      let list = pageInfo.list;
      let selected = this.selected;
      let selectedRows = [];
      for (let i = 0; i < list.length; i++) {
        let row = list[i];
        let ex = false;
        for (let h = 0; h < selected.length; h++) {
          let cuSelected = selected[h];
          if (cuSelected instanceof Object) {
            if (row[this.primaryKey] == cuSelected[this.primaryKey]) {
              ex = true;
              break;
            }
          } else {
            if (row[this.primaryKey] == cuSelected) {
              ex = true;
              break;
            }
          }
        }
        if (ex) {
          row._checked = true;
          selectedRows.push(row);
        }
      }
      this.selectedRows = selectedRows;
      return pageInfo;
    },
    loading: function() {
      let namespace = this.$props.namespace;
      return this.$store.state[namespace].loading;
    },
    columnsData: function() {
      let columns = this.columns;
      if (!columns) {
        columns = [];
      }
      let newColumns = [];
      for (let i = 0; i < columns.length; i++) {
        if (appService.hasPermission(columns[i].permissions)) {
          if (appService.hasRole(columns[i].roles)) {
            newColumns.push(columns[i]);
          }
        }
      }
      return newColumns;
    }
  },
  methods: {
    handlePageChange(currentPage) {
      this.$store.dispatch(`${this.$props.namespace}/query`, {
        limit: {
          currentPage: currentPage
        }
      });
    },
    handlePageSizeChange(pageSize) {
      this.$store.dispatch(`${this.$props.namespace}/query`, {
        limit: {
          currentPage: 1,
          pageSize: pageSize
        }
      });
    },
    handleSelectChange(selection) {
      let selectedRows = this.selectedRows;
      //老选择项id与老选择项的映射
      let olgSelectedMap = {};
      for (let i = 0; i < selectedRows.length; i++) {
        let selectedRow = selectedRows[i];
        if (!(selectedRow instanceof Object)) {
          let temp = {};
          temp[this.primaryKey] = selectedRow;
          selectedRow = temp;
        }
        olgSelectedMap[selectedRow[this.primaryKey]] = selectedRow;
      }
      //新选择项id与新选择项的映射
      let newSelectedMap = {};
      for (let i = 0; i < selection.length; i++) {
        newSelectedMap[selection[i][this.primaryKey]] = selection[i];
      }
      //获取取消选择项目
      let cancelSelect = [];
      for (let key in olgSelectedMap) {
        if (!newSelectedMap[key]) {
          cancelSelect.push(olgSelectedMap[key]);
        }
      }
      //获取新增选择项目
      let addSelect = [];
      for (let key in newSelectedMap) {
        if (!olgSelectedMap[key]) {
          addSelect.push(newSelectedMap[key]);
        }
      }
      this.$emit("on-selection-change", selection, addSelect, cancelSelect);
      this.$emit("onSelectionChange", selection, addSelect, cancelSelect);
    },
    handleSortChange(sort) {
      this.$emit("onSortChange", sort);
    },
    /** 加载数据 */
    loadData() {
      if (this.needQueryParam && !this.queryParam) {
        return;
      }
      if (this.$props.namespace) {
        this.cleanData();
        let queryParam = this.$props.queryParam;
        if (!queryParam) {
          queryParam = {};
        }
        this.$store.dispatch(`${this.$props.namespace}/query`, queryParam);
      }
    },
    /** 清空数据 */
    cleanData() {
      this.$store.commit(`${this.$props.namespace}/saveState`, {
        pageInfo: {
          list: [],
          pagination: {}
        }
      });
    }
  }
};
</script>
